﻿using log4net;
using System;
using System.Configuration;
using System.Threading;
using System.Windows.Forms;
using TimeSyncClient.Properties;
using TimeSyncUtil;

namespace TimeSyncClient
{
    public partial class Form1 : Form
    {
        public int AutoSyncMin = 60;

        public System.Threading.Timer NextAync;

        private static readonly ILog log = LogManager.GetLogger(typeof(Form1));

        public int NtpServerPort = 0;

        public string NtpServerAddress = "";

        public Form1()
        {
            InitializeComponent();
            int.TryParse(ConfigurationManager.AppSettings["NtpServerPort"], out NtpServerPort);
            int.TryParse(ConfigurationManager.AppSettings["AutoSyncMin"], out AutoSyncMin);
            NtpServerAddress = ConfigurationManager.AppSettings["NtpServerAddress"];
            this.WarnClose();
            this.BindNotifyIcon(时间同步工具, false);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            var time = SystemTimeHelper.GetLocalTime();
            ServerAddressTxtBox.Text = NtpServerAddress;
            ServerPortTxtBox.Text = NtpServerPort.ToString();
            SetIntervalChecked(AutoSyncMin);
        }

        private void SetIntervalChecked(int autoSyncMin)
        {
            if (autoSyncMin == 15)
            {
                radioButton1.Checked = true;
            }
            else if (autoSyncMin == 30)
            {
                radioButton2.Checked = true;
            }
            else if (autoSyncMin == 60)
            {
                radioButton3.Checked = true;
            }
            else if (autoSyncMin == 120)
            {
                radioButton4.Checked = true;
            }
            else if (autoSyncMin == 0)
            {
                radioButton5.Checked = true;
            }
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked)
            {
                AutoSyncMin = 15;
                StartNextAync();
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked)
            {
                AutoSyncMin = 30;
                StartNextAync();
            }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton3.Checked)
            {
                AutoSyncMin = 60;
                StartNextAync();
            }
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton4.Checked)
            {
                AutoSyncMin = 120;
                StartNextAync();
            }
        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton5.Checked)
            {
                AutoSyncMin = 0;
                StartNextAync();
            }
        }

        public void StartNextAync()
        {
            if (NextAync != null) NextAync.Dispose();

            if (AutoSyncMin == 0)
            {
                AppendTxt("停止同步");
                return;
            }

            var now = DateTime.Now;
            var totalMinutes = now.TimeOfDay.TotalMinutes;
            // 下一个同步时间距当天子时起应该有几个间隔
            int nextIntervalCount = (int)Math.Floor(totalMinutes / AutoSyncMin) + 1;

            // 下一个同步时间
            var nextAyncTime = now.Date.AddMinutes(nextIntervalCount * AutoSyncMin);

            log.Debug($"时间计算：{totalMinutes}/{AutoSyncMin}={nextIntervalCount} *{AutoSyncMin} ={nextAyncTime.ToShortTimeString()}");

            var delay = nextAyncTime - now;
            NextAync = new System.Threading.Timer(TimeSync, null, (int)delay.TotalMilliseconds, Timeout.Infinite);
            AppendTxt($"下一次同步时间:{nextAyncTime.ToShortTimeString()},同步间隔:{AutoSyncMin}min");
        }

        private void TimeSync(object state)
        {
            AppendTxt("开始同步");
            NtpClient client = new NtpClient(NtpServerAddress, NtpServerPort);
            try
            {
                AppendTxt("正在获取NTP服务器时间...");
                if (client.TryGetNetworkUTCTime(out DateTime networkUtcTime))
                {
                    string milliseconds = (networkUtcTime - DateTime.UtcNow).TotalMilliseconds.ToString("0.0");
                    AppendTxt($"已获取NTP服务器时间:{networkUtcTime.ToLocalTime().ToNtpTimeStr()}");
                    AppendTxt($"相比本地时间，差距{milliseconds}ms");
                    if (SystemTimeHelper.SetLocalTimeByDateTime(networkUtcTime.ToLocalTime()))
                    {
                        AppendTxt("已设置为系统时间");
                    }
                    else
                    {
                        AppendTxt("系统时间设置失败，可能需要管理员权限");
                    }
                }
                else
                {
                    AppendTxt($"获取NTP服务器时间失败");
                }

            }
            catch (Exception ex)
            {
                AppendTxt("同步失败，原因：" + ex.Message);
            }
            finally
            {
                StartNextAync();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TimeSync(null);
        }

        /// <summary>
        /// 更新服务端信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            NtpServerAddress = ServerAddressTxtBox.Text;
            int.TryParse(ServerPortTxtBox.Text, out NtpServerPort);
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings["NtpServerPort"].Value = NtpServerPort.ToString();
            config.AppSettings.Settings["NtpServerAddress"].Value = NtpServerAddress;
            config.AppSettings.Settings["autoSyncMin"].Value = (radioButton1.Checked ? 15 :
                radioButton2.Checked ? 30 : radioButton3.Checked ? 60 : radioButton4.Checked ? 120 : 0).ToString();
            config.Save();
            AppendTxt($"服务端信息已更新{NtpServerAddress}:{NtpServerPort.ToString()}");
        }

        private void xiaoxitz_TextChanged(object sender, EventArgs e)
        {

        }

        private void AppendTxt(string str)
        {
            log.Info(str);
            BeginInvoke(new Action(() =>
            {
                richTextBox1.AppendText($"{DateTime.Now.ToString()} {str}\n");
            }));
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            int maxLine = 100;//最大显示行数
            if (richTextBox1.Lines.Length > maxLine)
            {
                int curLines = richTextBox1.Lines.Length - maxLine;
                string[] lines = richTextBox1.Lines;
                Array.Copy(lines, curLines, lines, 0, maxLine);
                Array.Resize(ref lines, maxLine);
                richTextBox1.Lines = lines;
            }
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.ScrollToCaret();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.时间同步工具.ShowBalloonTip(1000);
            }
        }
    }
}
